home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / pascal / mouslib8.zip / MOUSELIB.PAS < prev    next >
Pascal/Delphi Source File  |  1993-02-25  |  48KB  |  1,269 lines

  1. (******************************************************************************
  2. *                                  MouseLib                                   *
  3. * Release 7.0 - Added demo program - Please refer to MOUSETST.PAS to                       *
  4. * see a demo of the mouseLib unit usage.                                                                             *
  5. ******************************************************************************)
  6. unit MouseLib;
  7. {$ifdef ovl}
  8.    {$F+}
  9. {$endif}
  10. interface
  11.  
  12. uses 
  13.     dos
  14.    ,tpDESQ { DESQview support unit }
  15.    ,video  { video supprot unit }
  16.     ;
  17.  
  18. const
  19.     MOUSEINT = $33; {mouse driver interrupt}
  20.     LEFTBUTTON = 1; {bit 0}
  21.     RIGHTBUTTON = 2; {bit 1}
  22.     MIDDLEBUTTON = 4; {bit 2}
  23.  
  24.     CURSOR_LOCATION_CHANGED = 1; {event mask bits}
  25.     LEFT_BUTTON_PRESSED = 2;
  26.     LEFT_BUTTON_RELEASED = 4;
  27.     RIGHT_BUTTON_PRESSED = 8;
  28.     RIGHT_BUTTON_RELEASED = 16;
  29.     MIDDLE_BUTTON_PRESSED = 32;
  30.     MIDDLE_BUTTON_RELEASED = 64;
  31.  
  32. type
  33.     mouseType = (twoButton,threeButton,another);
  34.     buttonState = (buttonDown,buttonUp);
  35.     direction = (moveRight,moveLeft,moveUp,moveDown,noMove);
  36.     grCursorType = record
  37.         xH,yH : byte; {x,y Hot Point}
  38.         data  : pointer;  {cursor look pointer}
  39.     end;
  40. var
  41.     mouse_present : boolean;
  42.     mouse_buttons : mouseType;
  43.     eventX,eventY,eventButtons : word; {any event handler should update}
  44.     eventhappened : Boolean;       {these vars to use getLastEvent }
  45.     XMotions,YMotions : word;       {per 8 pixels}
  46.     mouseCursorLevel : integer;
  47.     {if > 0 mouse cursor is visiable, otherwise not, containes the level
  48.      of showMouseCursor/hideMouseCursor}
  49.    fontPoints : byte;
  50. var
  51.     maxMouseX     : integer; 
  52.     maxMouseY    : integer; 
  53.  
  54. const    LastMask : word = 0;
  55.     lastHandler : pointer = Nil;
  56.  
  57.     {when changing the interrupt handler temporarily, save BEFORE the
  58.         change these to variables, and restore them when neccessary}
  59.  
  60.     lastCursor : grCursorType = (
  61.         xH : 0;
  62.         yH : 0;
  63.         data : nil );
  64.  
  65.     {when changing graphic cursor temporarily, save these values BEFORE
  66.         the change, and restore when neccessary}
  67.  
  68. const
  69.    click_repeat  = 10; { Recommended value for waitForRelease timeOut }
  70.     mouseTextScale = 8;
  71. (*****    mouse scale factor in text *****)
  72.    vgaTextGraphicCursor : boolean = false; { this is not the default .. }
  73.  
  74. procedure initMouse; {when replacing mouse mode do that..!}
  75. procedure showMouseCursor;
  76. procedure hideMouseCursor;
  77. function getMouseX : word;
  78. function getMouseY : word;
  79. function getButton(Button : Byte) : buttonState;
  80. function buttonPressed : boolean;
  81. procedure setMouseCursor(x,y : word);
  82. function LastXPress(Button : Byte) : word;
  83. function LastYPress(Button : Byte) : word;
  84. function ButtonPresses(Button : Byte) : word; {from last last check}
  85. function LastXRelease(Button : Byte) : word;
  86. function LastYRelease(Button : Byte) : word;
  87. function ButtonReleases(Button : Byte) : word; {from last last check}
  88. procedure mouseBox(left,top,right,bottom : word); {limit mouse rectangle}
  89. procedure graphicMouseCursor(xHotPoint,yHotPoint : byte; dataOfs : pointer);
  90. procedure HardwareTextCursor(fromLine,toLine : byte);
  91. procedure softwareTextCursor(screenMask,cursorMask : word);
  92. function recentXmovement : direction;
  93. function recentYmovement : direction;
  94. procedure setArrowCursor;
  95. procedure setWatchCursor;
  96. procedure setUpArrowCursor;
  97. procedure setLeftArrowCursor;
  98. procedure setCheckMarkCursor;
  99. procedure setPointingHandCursor;
  100. procedure setDiagonalCrossCursor;
  101. procedure setRectangularCrossCursor;
  102. procedure setHourGlassCursor;
  103. procedure setNewWatchCursor;
  104. procedure setEventHandler(mask : word; handler    : pointer);
  105. procedure setDefaultHandler(mask : word);
  106. procedure enableLightPenEmulation;
  107. procedure disableLightPenEmulation;
  108. procedure defineSensetivity(x,y : word);
  109. procedure setHideCursorBox(left,top,right,bottom : word);
  110. procedure defineDoubleSpeedTreshHold(treshHold : word);
  111. procedure disableTreshHold;
  112. procedure defaultTreshHold;
  113. procedure setMouseGraph;
  114. procedure resetMouseGraph;
  115. procedure waitForRelease(timeOut : word);
  116. procedure swapEventHandler(mask : word; handler : pointer); 
  117. { return old in lastMask and lastHandler }
  118. function getMouseSaveStateSize : word;
  119. procedure interceptMouse; { get mouse from interrupted program, and stop it .. }
  120. procedure restoreMouse;
  121. procedure setVgaTextGraphicCursor;
  122. procedure resetVgaTextGraphicCursor;
  123.  
  124. (******************************************************************************
  125. *                                  MouseLib                                   *
  126. *                                                                             *
  127. *                        mouseLib     -      Release 2    and above                  *
  128. *                                                                                                 *
  129. *  because of quirks in hercules graphic mode that is not detectable          *
  130. *   by the mouse driver we have to know when we initMouse if we want          *
  131. *   to check for graphic mode or not, if we do we must perform a                 *
  132. *   setMouseGraph before initGraph, to initGraph in text mode we must         *
  133. *   resetMouseGraph before.. , if these calling conventions are not           *
  134. *   taken we might have problems in hercules cards!                                 *
  135. *                                                                             *
  136. *  each call to hideMouseCursor must be balanced by a matching call           *
  137. *   to showMouseCursor, 2 calls to hideMou.. and only 1 to showM..             *
  138. *   will not show the mouse cursor on the screen!                                    *
  139. *                                                                             *
  140. *  if we want to use the text "graphic" mouse, we must perform a              *
  141. *   setVgaTextGraphicCursor call before we call initMouse ...                 *
  142. ******************************************************************************)
  143.  
  144. implementation
  145.  
  146. {$ifdef ver60}
  147. const
  148.    seg0040 = $40; { needed - in Ver7.0 points to bios area, 
  149.                              needed so protected mode will not crash on
  150.                              RT-error 216 (exception 13 }
  151.    segB800 = $b800;
  152.    segA000 = $a000;
  153. {$endif}   
  154.  
  155. const watchData : array [0..31] of word =
  156.     ($E007,$C003,$8001,$0,$0,$0,$0,$0,$0,$0,$0,$0,$0,$8001,$C003,$E007,
  157.      $0,$1FF8,$318C,$6186,$4012,$4022,$4042,$718C,$718C,$4062,$4032,
  158.      $4002,$6186,$318C,$1FF8,$0);
  159.  
  160. const arrowData : array [0..31] of word =
  161.     ($FFFF,$8FFF,$8FFF,$87FF,$83FF,$81FF,$80FF,$807F,$803F,$801F,$800F,
  162.      $801F,$807F,$887F,$DC3F,$FC3F,
  163.      $0,$0,$2000,$3000,$3800,$3C00,$3E00,$3F00,$3F80,$3FC0,
  164.      $3FE0,$3E00,$3300,$2300,$0180,$0180);
  165.  
  166. const UpArrowCursor : array [0..31] of word =
  167.          ($f9ff,$f0ff,$e07f,$e07f,$c03f,$c03f,$801f,$801f,
  168.           $f,$f,$f0ff,$f0ff,$f0ff,$f0ff,$f0ff,$f0ff,
  169.           $0,$600,$f00,$f00,$1f80,$1f80,$3fc0,$3fc0,
  170.           $7fe0,$600, $600, $600, $600, $600, $600, $600);
  171.  
  172. const  LeftArrowCursor : array [0..31] of word
  173.        = ($fe1f,$f01f,$0,   $0,   $0,   $f01f,$fe1f,$ffff,
  174.           $ffff,$ffff,$ffff,$ffff,$ffff,$ffff,$ffff,$ffff,
  175.           $0,   $c0,  $7c0, $7ffe,$7c0, $c0,  $0,   $0,
  176.           $0,   $0,   $0,   $0,   $0,   $0,   $0,   $0);
  177.  
  178. const  CheckMarkCursor : array [0..31] of word
  179.        = ($fff0,$ffe0,$ffc0,$ff81,$ff03,$607, $f,   $1f,
  180.           $c03f,$f07f,$ffff,$ffff,$ffff,$ffff,$ffff,$ffff,
  181.           $0,   $6,   $c,   $18,  $30,  $60,  $70c0,$1d80,
  182.           $700, $0,   $0,   $0,   $0,   $0,   $0,   $0);
  183.  
  184. const  PointingHandCursor : array [0..31] of word
  185.        = ($e1ff,$e1ff,$e1ff,$e1ff,$e1ff,$e000,$e000,$e000,
  186.           $0,   $0,   $0,   $0,   $0,   $0,   $0,   $0,
  187.           $1e00,$1200,$1200,$1200,$1200,$13ff,$1249,$1249,
  188.           $f249,$9001,$9001,$9001,$8001,$8001,$8001,$ffff);
  189.  
  190. const  DiagonalcrossCursor : array [0..31] of word
  191.        = ($7e0, $180, $0,   $c003,$f00f,$c003,$0,   $180,
  192.           $7e0, $ffff,$ffff,$ffff,$ffff,$ffff,$ffff,$ffff,
  193.           $0,   $700e,$1c38,$660, $3c0, $660, $1c38,$700e,
  194.           $0,   $0,   $0,   $0,   $0,   $0,   $0,   $0);
  195.  
  196. const  
  197.    RectangularCrossCursor : array [0..31] of word
  198.        = ($fc3f,$fc3f,$fc3f,$0,$0,   $0,   $fc3f,$fc3f,
  199.           $fc3f,$ffff,$ffff,$ffff,$ffff,$ffff,$ffff,$ffff,
  200.           $0,   $180, $180, $180, $7ffe,$180, $180, $180,
  201.           $0,   $0,   $0,   $0,   $0,   $0,   $0,   $0);
  202.  
  203. const  
  204.    HourglassCursor : array [0..31] of word
  205.        = ($0,   $0,   $0,   $0,   $8001,$c003,$e007,$f00f,
  206.           $e007,$c003,$8001,$0,   $0,   $0,   $0,   $ffff,
  207.           $0,   $7ffe,$6006,$300c,$1818,$c30, $660, $3c0,
  208.           $660, $c30, $1998,$33cc,$67e6,$7ffe,$0,   $0);
  209.  
  210. const 
  211.    newWatchCursor : array [0..31] of word
  212.        = ( $ffff, $c003, $8001, $0, $0, $0, $0, $0, $0, 
  213.            $0, $0, $0, $0, $8001, $c003, $ffff, $0, $0, 
  214.            $1ff8, $2004, $4992, $4022, $4042, $518a, $4782, 
  215.            $4002, $4992, $4002, $2004, $1ff8, $0, $0 );
  216.  
  217. (* these are the screen and cursor masks for vgaTextGraphicCursor mode, we
  218.    save them in screen (16 .. ) cursor (16 .. ) order *)
  219.  
  220. const 
  221.    vgaArrowData : array [ 0 .. 31 ] of longint = 
  222.    ( $3fffffff, $1fffffff, $0fffffff, $07ffffff, $03ffffff, $01ffffff,
  223.      $00ffffff, $007fffff, $003fffff, $007fffff, $01ffffff, $10ffffff,
  224.      $b0ffffff, $f87fffff, $f87fffff, $fcffffff, (* now cursor *)
  225.      $00000000, $40000000, $60000000, $70000000, $78000000, $7c000000,
  226.      $7e000000, $7f000000, $7f800000, $7f000000, $7c000000, $46000000,
  227.      $06000000, $03000000, $03000000, $00000000);
  228.  
  229. type
  230.    vgaTextGraphicArrayPtr = ^ vgaTextGraphicArray;
  231.    vgaTextGraphicArray = array [ 0 .. 31 ] of longint;
  232.  
  233. const 
  234.    vgaTextGraphicPtr : vgaTextGraphicArrayPtr = @vgaArrowData;
  235.  
  236. const 
  237.    mouseGraph : boolean = false; {assume text mode upon entry}
  238.  
  239. type box = record
  240.         left,top,right,bottom : word;
  241.     end; {Do not change field order !!!}
  242.  
  243.    charDefsTypePtr = ^ charDefsType;
  244.    charDefsType = array[0 .. (32 * 8)] of byte;
  245.  
  246. var 
  247.    hideBox : box;
  248.    reg : registers;  {general registers used}
  249.    grMode,
  250.    grDrv : integer; {detect graphic mode if any}
  251.    grCode : integer;     {return initgraph code in here}
  252.    interceptX, 
  253.    interceptY : word;
  254.    VGAStoredArray : array [ 1 .. 3, 1 .. 3 ] of byte; 
  255.    { in vgaTextGraphicCursor mode we change up to 9 characters, on the fly .. 
  256.      here we save them }
  257.    lastEventX, lastEventY : word; { in vgaTextGraphicCursor mode, we need 
  258.                                     the last ... }
  259.    hasStoredArray : boolean; { true when need to restore screen in vgaGrTxtCrsr mode }
  260.  
  261. const
  262.    charDefs : charDefsTypePtr = nil;
  263.  
  264.    charHeight = 16;  { character height }
  265.    defChar    = $d0; { character range that will be changed on the fly .. }
  266.  
  267. (******************************************************************************
  268. *                                  callMouse                                  *
  269. *                                                                             *
  270. * used to call mouse interrupt with global data reg - used as parameters      *
  271. ******************************************************************************)
  272. procedure callMouse;
  273. begin
  274.         intr(MOUSEINT,REG);
  275. end; {callMouse}
  276.  
  277. (******************************************************************************
  278. *                                  initMouse                                  *
  279. * For some reason grCode is assigned a value of -11,($FFF5) in the second time*
  280. *  we call initmouse after we allready are in graphics mode, override.. was   *
  281. *  born because of that situation.                                            *
  282. ******************************************************************************)
  283. procedure initMouse;
  284. var
  285.     overRideDriver : boolean; { true if we over-ridden stupid driver hercules bug }
  286.     tempVideoMode  : byte;
  287. begin
  288.    overRideDriver := false;
  289.    if (mouseGraph and (mem[seg0040:$49] = 7)) then begin { assume no mda - hercules }
  290.        mem[seg0040:$49] := 6;
  291.       overRideDriver := true;
  292.    end; {trick stupid mouse driver to know we are in graphic mode}
  293.    if (vgaTextGraphicCursor) then begin
  294.       tempVideoMode := mem[seg0040:$49];
  295.        mem[seg0040:$49] := 6; { pixel movements of 1 ... }
  296.    end; { vgaTextGraphicCursor .. }
  297.     with reg do begin
  298.         ax:=0; {detect genius mouse}
  299.         bx:=0; {be sure what mode we get}
  300.         callMouse;
  301.         mouse_present := (ax <> 0); {not an iret..}
  302.         if ((bx and 2) <> 0)
  303.             then mouse_buttons := twoButton
  304.         else if ((bx and 3) <> 0)
  305.             then mouse_buttons := threeButton
  306.         else mouse_buttons := another; {unknown to us}
  307.     end; {with}
  308.    if (overRideDriver) then
  309.        mem[seg0040:$49] := 7; {restore the stupid situation}
  310.    if (vgaTextGraphicCursor) then begin
  311.       mem[seg0040:$49] := tempVideoMode; { restore for later use ... }
  312.    end;
  313.    if (not vgaTextGraphicCursor) then
  314.       fontPoints := mouseTextScale { bios rows }
  315.    else
  316.       fontPoints := mem[seg0040:$85];
  317.    maxMouseX := maxX * mouseTextScale;
  318.    maxMouseY := maxY * fontPoints;
  319.    mouseBox(0, 0, visibleX * mouseTextScale - 1, visibleY * fontPoints -1);
  320.    eventButtons := 0;
  321.    eventhappened := False;
  322.    XMotions := 8;
  323.    YMotions := 16;
  324.    mouseCursorLevel := 0; { not visiable, one show to appear }
  325.    hasStoredArray := false; { we have no saved array for vgaTextGraphicCursor mode }
  326.    setMouseCursor(visibleX * mouseTextScale div 2, visibleY * fontPoints div 2);
  327.    eventX := getMouseX;
  328.    eventY := getMouseY;
  329.    lastEventX := eventX;
  330.    lastEventY := eventY;
  331. (*   setMouseCursor(0, 0); *)
  332. end; {initMouse}
  333.  
  334. (******************************************************************************
  335. *                               VGAscreen2Array                               *
  336. * copy our screen saved array, before fonts are changed ..                    *
  337. * if newPosition is true, use eventX, eventY, otherwise - use lastEventX and  *
  338. * lastEventY                                                                  *
  339. * defaultRange = true -> draw changed on the fly, otherwise , regard s2a ..   *
  340. * s2a = screen2Array if true, array to screen otherwise ..                    *
  341. ******************************************************************************)
  342. procedure VGAscreen2Array(newPosition, s2a, defaultRange : boolean);
  343. var
  344.    x, y : word;
  345.    w, h : word; { width and height of array .. }
  346.    o, l : word; { o - offset into screen, l = line size in bytes, in display }
  347.    i, j : byte;
  348. begin
  349.    if (newPosition) then begin
  350.       x := eventX div mouseTextScale;
  351.       y := eventY div fontPoints;
  352.    end else begin
  353.       x := lastEventX  div mouseTextScale;
  354.       y := lastEventY div fontPoints;
  355.    end;
  356.    w := visibleX - x;
  357.    if (w > 3) then
  358.       w := 3; { just double checking ... }
  359.    h := visibleY - y;
  360.    if (h > 3) then
  361.       h := 3;
  362.    o := 2 * x + 2 * visibleX * y; { 2 bytes per character -> char + attribute }
  363.    l := 2 * visibleX - 2 * w; { add when screen line overlap ... }
  364.    if (defaultRange) then begin
  365.       for i := 0 to h - 1 do begin
  366.          for j := 0 to w - 1 do begin
  367.             mem[segb800:o] := defChar + i * 3 + j;
  368.             inc(o, 2);
  369.          end; { for j .. }
  370.          inc(o, l); { next line .. }
  371.       end; { for i }
  372.    end else 
  373.       if (s2a) then begin { copy screen 2 array }
  374.          for i := 1 to h do begin
  375.             for j := 1 to w do begin
  376.                VGAStoredArray[i, j] := mem[segb800:o];
  377.                inc(o, 2); { next character }
  378.             end; { for j .. }
  379.             inc(o, l); { next line .. }
  380.          end; { for i .. }
  381.       end else begin {copy array 2 screen }
  382.          for i := 1 to h do begin
  383.             for j := 1 to w do begin
  384.                mem[segb800:o] := VGAStoredArray[i, j];
  385.                inc(o, 2); { next character }
  386.             end; { for j .. }
  387.             inc(o, l); { next line .. }
  388.          end; { for i .. }
  389.       end; { if s2a .. }
  390. end; {VGAscreen2Array}
  391.  
  392. (******************************************************************************
  393. *                          drawVGATextGraphicCursor                           *
  394. * here we do the black magic of putting it on the screen !                    *
  395. * this code is based on the code presented by Dave Kirsch, in his MOU code,   *
  396. * which was ported by Duncan Murdoch. This code was changed to be integrated  *
  397. * into the mouseLib unit, and enhanced where possible.                        *
  398. ******************************************************************************)
  399. procedure drawVGATextGraphicCursor;
  400. type
  401.    lp = ^ longint;
  402. const
  403.    sequencerPort     = $3c4;
  404.    sequencerAddrMode = $704;
  405.    sequencerAddrNrml = $302; { write maps 0, 1 }
  406.    vgaControlerPort  = $3ce;
  407.    cpuReadMap2       = $204;
  408.    cpuWriteMap2      = $402;
  409.    mapStartAddrA000  = $406;
  410.    mapStartAddrB800  = $e06;
  411.    oddEvenAddr       = $304;
  412. var
  413.    o, s        : word;
  414.    i, j        : integer;
  415.    s1, s2, s3  : word;
  416.    a           : longint;
  417.    d, mc, ms   : lp;
  418. begin
  419. { we already have stored in vgaStoredArray what we have to store .. }
  420.    asm
  421.       pushf;
  422.       cli;   { disable interrupts }
  423.       mov dx, sequencerPort;
  424.       mov ax, sequencerAddrMode;
  425.       out dx, ax;
  426.  
  427.       mov dx, vgaControlerPort;
  428.       mov ax, cpuReadMap2;
  429.       out dx, ax
  430.  
  431.       mov ax, 5
  432.       out dx, ax { disable odd-even addr mode }
  433.       mov ax, mapStartAddrA000;
  434.       out dx, ax;
  435.       popf;
  436.    end; { asm }
  437.  
  438.    (* now copy character def. tables for the characters changed on the fly *)
  439.  
  440.    o := 0;
  441.    for i := 1 to 3 do begin
  442.       s1 := VGAStoredArray[i, 1] * 32;
  443.       s2 := VGAStoredArray[i, 2] * 32;
  444.       s3 := VGAStoredArray[i, 3] * 32;
  445.       for j := 1 to fontPoints do begin
  446.          inc(o); { skip 4th byte }
  447.          charDefs^[o] := mem[segA000:s3]; 
  448.             { this code is changed to minimize DS variable space ! - RL }
  449.          inc(o);
  450.          charDefs^[o] := mem[segA000:s2];
  451.          inc(o);
  452.          charDefs^[o] := mem[segA000:s1];
  453.          inc(o);
  454.          inc(s1);
  455.          inc(s2);
  456.          inc(s3);
  457.       end; { for j }
  458.    end; { for i } 
  459.  
  460.    (* now we are Drawing the cursor by ANDing with the screenMask, 
  461.       and ORing with the cursor mask *)
  462.  
  463.    s := eventX mod mouseTextScale; { shift calc .. }
  464.    a := $ff000000 shl (mouseTextScale - s);
  465.  
  466.    (* now we have the shift and additive mask .. *)
  467.  
  468.    d := @chardefs^[(eventY mod fontPoints) * sizeof(longint)];
  469.    ms := @vgaTextGraphicPtr^;
  470.    mc := @vgaTextGraphicPtr^[charHeight];
  471.    for i := 1 to charHeight do begin
  472.       d^ := (d^ and ((ms^ shr s) or a)) or (mc^ shr s);
  473.       inc(word(d), sizeof(longint)); { we change only the offset of the pointer }
  474.       inc(word(mc), sizeof(longint)); { we change only the offset of the pointer }
  475.       inc(word(ms), sizeof(longint)); { we change only the offset of the pointer }
  476.    end; { for i .. } 
  477.    (* here we ANDed with the screen mask, and ORed with the cursor mask *)
  478.  
  479.    asm
  480.       mov dx, sequencerPort;
  481.       mov ax, cpuWriteMap2;
  482.       out dx, ax
  483.    end;
  484.  
  485.    o := 0;
  486.    for i := 0 to 2 do begin
  487.       s1 := (defChar + 3 * i    ) * 32;
  488.       s2 := (defChar + 3 * i + 1) * 32;
  489.       s3 := (defChar + 3 * i + 2) * 32;
  490.       for j := 1 to fontPoints do begin
  491.          inc(o); { skip 4th byte }
  492.          mem[segA000:s3] := charDefs^[o]; 
  493.             { this code is changed to minimize DS variable space ! - RL }
  494.          inc(o);
  495.          mem[segA000:s2] := charDefs^[o];
  496.          inc(o);
  497.          mem[segA000:s1] := charDefs^[o];
  498.          inc(o);
  499.          inc(s1);
  500.          inc(s2);
  501.          inc(s3);
  502.       end; { for j }
  503.    end; { for i }
  504.  
  505.    (* now we will return the graphic adapter back to normal *)
  506.  
  507.    asm
  508.       pushf;
  509.       cli; { disable intr .. }
  510.       mov dx, sequencerPort;
  511.       mov ax, sequencerAddrNrml;
  512.       out dx, ax;
  513.       mov ax, oddEvenAddr;
  514.       out dx, ax;
  515.  
  516.       mov dx, vgaControlerPort;
  517.       mov ax, 4; { map 0 for cpu reads }
  518.       out dx, ax;
  519.       mov ax, $1005;
  520.       out dx, ax;
  521.       mov ax, mapStartAddrB800;
  522.       out dx, ax
  523.       popf;
  524.    end; { asm }
  525.  
  526.    vgaScreen2Array(true, false, true); { go ahead and paint it .. }
  527.  
  528. end; {drawVGATextGraphicCursor}
  529.  
  530. (******************************************************************************
  531. *                               showMouseCursor                               *
  532. ******************************************************************************)
  533. procedure showMouseCursor;
  534.  
  535. begin
  536.     inc(mouseCursorLevel);
  537.    if (not vgaTextGraphicCursor) then begin
  538.        reg.ax:=1; {enable cursor display}
  539.        callMouse;
  540.    end else if ((mouseCursorLevel = 1) and mouse_present) then begin
  541.       vgaScreen2Array(true, true, false);
  542.       hasStoredArray := true;
  543.       drawVGATextGraphicCursor;
  544.    end;
  545. end; {showMouseCursor}
  546.  
  547. (******************************************************************************
  548. *                               hideMouseCursor                               *
  549. ******************************************************************************)
  550. procedure hideMouseCursor;
  551.  
  552. begin
  553.     dec(mouseCursorLevel);
  554.    if (not vgaTextGraphicCursor) then begin
  555.        reg.ax:=2; {disable cursor display}
  556.        callMouse;
  557.    end else if ((mouseCursorLevel = 0) and (hasStoredArray)) then begin
  558.       vgaScreen2Array(false, false, false);
  559.       hasStoredArray := false;
  560.    end;
  561. end; {hideMouseCursor}
  562.  
  563. (******************************************************************************
  564. *                                  getMouseX                                  *
  565. ******************************************************************************)
  566. function getMouseX : word;
  567.  
  568. begin
  569.     reg.ax := 3;
  570.     callMouse;
  571.     getMouseX := reg.cx;
  572. end; {getMouseX}
  573.  
  574. (******************************************************************************
  575. *                                  getMouseY                                  *
  576. ******************************************************************************)
  577. function getMouseY : word;
  578.  
  579. begin
  580.     reg.ax := 3;
  581.     callMouse;
  582.     getMouseY := reg.dx;
  583. end; {getMouseX}
  584.  
  585. (******************************************************************************
  586. *                                  getButton                                  *
  587. ******************************************************************************)
  588. function getButton(Button : Byte) : buttonState;
  589.  
  590. begin
  591.     reg.ax := 3;
  592.     callMouse;
  593.     if ((reg.bx and Button) <> 0) then
  594.         getButton := buttonDown
  595.         {bit 0 = left, 1 = right, 2 = middle}
  596.     else getButton := buttonUp;
  597. end; {getButton}
  598.  
  599. (******************************************************************************
  600. *                                buttonPressed                                *
  601. ******************************************************************************)
  602. function buttonPressed : boolean;
  603.  
  604. begin
  605.     reg.ax := 3;
  606.     callMouse;
  607.     if ((reg.bx and 7) <> 0) then
  608.         buttonPressed := True
  609.     else buttonPressed := False;
  610. end; {buttonPressed}
  611.  
  612. (******************************************************************************
  613. *                               setMouseCursor                                *
  614. ******************************************************************************)
  615. procedure setMouseCursor(x,y : word);
  616.  
  617. begin
  618.     with reg do begin
  619.         ax := 4;
  620.         cx := x;
  621.         dx := y; {prepare parameters}
  622.         callMouse;
  623.     end; {with}
  624. end; {setMouseCursor}
  625.  
  626. (******************************************************************************
  627. *                                 lastXPress                                  *
  628. ******************************************************************************)
  629. function lastXPress(Button : Byte) : word;
  630.  
  631. begin
  632.     reg.ax := 5;
  633.     reg.bx := Button;
  634.     callMouse;
  635.     lastXPress := reg.cx;
  636. end; {lastXpress}
  637.  
  638. (******************************************************************************
  639. *                                 lastYPress                                  *
  640. ******************************************************************************)
  641. function lastYPress(Button : Byte) : word;
  642.  
  643. begin
  644.     reg.ax := 5;
  645.     reg.bx := Button;
  646.     callMouse;
  647.     lastYPress := reg.dx;
  648. end; {lastYpress}
  649.  
  650. (******************************************************************************
  651. *                                buttonPresses                                *
  652. ******************************************************************************)
  653. function buttonPresses(Button : Byte) : word; {from last check}
  654.  
  655. begin
  656.     reg.ax := 5;
  657.     reg.bx := Button;
  658.     callMouse;
  659.     buttonPresses := reg.bx;
  660. end; {buttonPresses}
  661.  
  662. (******************************************************************************
  663. *                                lastXRelease                                 *
  664. ******************************************************************************)
  665. function lastXRelease(Button : Byte) : word;
  666.  
  667. begin
  668.     reg.ax := 6;
  669.     reg.bx := Button;
  670.     callMouse;
  671.     lastXRelease := reg.cx;
  672. end; {lastXRelease}
  673.  
  674. (******************************************************************************
  675. *                                lastYRelease                                 *
  676. ******************************************************************************)
  677. function lastYRelease(Button : Byte) : word;
  678.  
  679. begin
  680.     reg.ax := 6;
  681.     reg.bx := Button;
  682.     callMouse;
  683.     lastYRelease := reg.dx;
  684. end; {lastYRelease}
  685.  
  686. (******************************************************************************
  687. *                               buttonReleases                                *
  688. ******************************************************************************)
  689. function buttonReleases(Button : Byte) : word; {from last check}
  690.  
  691. begin
  692.     reg.ax := 6;
  693.     reg.bx := Button;
  694.     callMouse;
  695.     buttonReleases := reg.bx;
  696. end; {buttonReleases}
  697.  
  698. (******************************************************************************
  699. *                                    swap                                     *
  700. ******************************************************************************)
  701. procedure swap(var a,b : word);
  702.  
  703. var c : word;
  704.  
  705. begin
  706.     c := a;
  707.     a := b;
  708.     b := c; {swap a and b}
  709. end; {swap}
  710.  
  711. (******************************************************************************
  712. *                                  mouseBox                                   *
  713. ******************************************************************************)
  714. procedure mouseBox(left,top,right,bottom : word);
  715.  
  716. begin
  717.     if (left > right) then swap(left,right);
  718.     if (top > bottom) then swap(top,bottom); {make sure they are ordered}
  719.     reg.ax := 7;
  720.     reg.cx := left;
  721.     reg.dx := right;
  722.     callMouse; {set x range}
  723.     reg.ax := 8;
  724.     reg.cx := top;
  725.     reg.dx := bottom;
  726.     callMouse; {set y range}
  727. end; {mouseBox}
  728.  
  729. (******************************************************************************
  730. *                             graphicMouseCursor                              *
  731. ******************************************************************************)
  732. procedure graphicMouseCursor(xHotPoint,yHotPoint : byte; dataOfs : pointer);
  733.  
  734. {define 16*16 cursor mask and screen mask, pointed by data,
  735.     dataOfs is pointer to data of the masks.}
  736.  
  737. begin
  738.     reg.ax := 9;
  739.     reg.bx := xHotPoint;
  740.     reg.cx := yHotPoint;
  741.     reg.dx := ofs(dataOfs^);    {DS:DX point to masks}
  742.     reg.es := seg(dataOfs^);
  743.     callMouse;
  744.     lastCursor.xH := xHotPoint;
  745.     lastCursor.yH := yHotPoint;
  746.     lastCursor.data := dataOfs;
  747.     {save it in lastCursor, if someone needs to change cursor temporary}
  748. end; {graphicMouseCursor}
  749.  
  750. (******************************************************************************
  751. *                             HardwareTextCursor                              *
  752. ******************************************************************************)
  753. procedure HardwareTextCursor(fromLine,toLine : byte);
  754.  
  755. {set text cursor to text, using the scan lines from..to,
  756.     same as intr 10 cursor set in bios :
  757.     color scan lines 0..7, monochrome 0..13 }
  758.  
  759. begin
  760.     reg.ax := 10;
  761.     reg.bx := 1; {hardware text}
  762.     reg.cx := fromLine;
  763.     reg.dx := toLine;
  764.     callMouse;
  765. end; {hardwareTextCursor}
  766.  
  767. (******************************************************************************
  768. *                             softwareTextCursor                              *
  769. ******************************************************************************)
  770. procedure softwareTextCursor(screenMask,cursorMask : word);
  771.  
  772. { when in this mode the cursor will be achived by ANDing the screen word
  773.     with the screen mask (Attr,Char in high,low order) and
  774.     XORing the cursor mask, ussually used by putting the screen attr
  775.     we want preserved in screen mask (and 0 into screen mask character
  776.     byte), and character + attributes we want to set into cursor mask}
  777.  
  778. begin
  779.     reg.ax := 10;
  780.     reg.bx := 0;    {software cursor}
  781.     reg.cx := screenMask;
  782.     reg.dx := cursorMask;
  783.     callMouse;
  784. end; {softwareMouseCursor}
  785.  
  786. (******************************************************************************
  787. *                               recentXmovement                               *
  788. ******************************************************************************)
  789. function recentXmovement : direction;
  790.  
  791. {from recent call to which direction did we move ?}
  792.  
  793. var d : integer;
  794.  
  795. begin
  796.     reg.ax := 11;
  797.     callMouse;
  798.     d := reg.cx;
  799.     if (d > 0)
  800.         then recentXmovement := moveRight
  801.     else if (d < 0)
  802.         then recentXmovement := moveLeft
  803.     else recentXmovement := noMove;
  804. end; {recentXmovement}
  805.  
  806. (******************************************************************************
  807. *                               recentYmovement                               *
  808. ******************************************************************************)
  809. function recentYmovement : direction;
  810.  
  811. {from recent call to which direction did we move ?}
  812.  
  813. var 
  814.    d : integer;
  815. begin
  816.     reg.ax := 11;
  817.     callMouse;
  818.     d := reg.dx;
  819.     if (d > 0)
  820.         then recentYmovement := moveDown
  821.     else if (d < 0)
  822.         then recentYmovement := moveUp
  823.     else recentYmovement := noMove;
  824. end; {recentYmovement}
  825.  
  826. (******************************************************************************
  827. *                               setWatchCursor                                *
  828. ******************************************************************************)
  829. procedure setWatchCursor;
  830. begin
  831.     graphicMouseCursor(0,0,@watchData);
  832. end; {setWatchCursor}
  833.  
  834. (******************************************************************************
  835. *                              setNewWatchCursor                              *
  836. ******************************************************************************)
  837. procedure setNewWatchCursor; 
  838. begin
  839.    graphicMouseCursor(0, 0, @newWatchCursor);
  840. end; {setNewWatchCursor}
  841.  
  842. (******************************************************************************
  843. *                              setUpArrowCursor                               *
  844. ******************************************************************************)
  845. procedure setUpArrowCursor;
  846. begin
  847.     graphicMouseCursor(5, 0, @upArrowCursor);
  848. end; {setUpArrowCursor}
  849.  
  850. (******************************************************************************
  851. *                             setLeftArrowCursor                              *
  852. ******************************************************************************)
  853. procedure setLeftArrowCursor;
  854. begin
  855.     graphicMouseCursor(0, 3, @leftArrowCursor);
  856. end; {setLeftArrowCursor}
  857.  
  858. (******************************************************************************
  859. *                             setCheckMarkCursor                              *
  860. ******************************************************************************)
  861. procedure setCheckMarkCursor;
  862. begin
  863.     graphicMouseCursor(6, 7, @checkMarkCursor);
  864. end; {setCheckMarkCursor}
  865.  
  866. (******************************************************************************
  867. *                            setPointingHandCursor                            *
  868. ******************************************************************************)
  869. procedure setPointingHandCursor;
  870. begin
  871.     graphicMouseCursor(5, 0, @pointingHandCursor);
  872. end; {setPointingHandCursor}
  873.  
  874. (******************************************************************************
  875. *                           setDiagonalCrossCursor                            *
  876. ******************************************************************************)
  877. procedure setDiagonalCrossCursor;
  878. begin
  879.     graphicMouseCursor(7, 4, @diagonalCrossCursor);
  880. end; {setDiagonalCrossCursor}
  881.  
  882. (******************************************************************************
  883. *                          setRectangularCrossCursor                          *
  884. ******************************************************************************)
  885. procedure setRectangularCrossCursor;
  886. begin
  887.     graphicMouseCursor(7, 4, @rectangularCrossCursor);
  888. end; {setRectangularCrossCursor}
  889.  
  890. (******************************************************************************
  891. *                             setHourGlassCursor                              *
  892. ******************************************************************************)
  893. procedure setHourGlassCursor;
  894. begin
  895.     graphicMouseCursor(7, 7, @hourGlassCursor);
  896. end; {setHourGlassCursor}
  897.  
  898. (******************************************************************************
  899. *                               setArrowCursor                                *
  900. ******************************************************************************)
  901. procedure setArrowCursor;
  902. begin
  903.     graphicMouseCursor(1,1,@arrowData);
  904. end; {setArrowCursor}
  905.  
  906. (******************************************************************************
  907. *                               setEventHandler                               *
  908. ******************************************************************************)
  909. procedure setEventHandler(mask : word; handler    : pointer);
  910.  
  911. {handler must be a far interrupt routine }
  912.  
  913. begin
  914.     reg.ax := 12; {set event handler function in mouse driver}
  915.     reg.cx := mask;
  916.     reg.es := seg(handler^);
  917.     reg.dx := ofs(handler^);
  918.     callMouse;
  919.     lastMask := mask;
  920.     lastHandler := handler;
  921. end; {set event Handler}
  922.  
  923. (******************************************************************************
  924. *                               defaultHandler                                *
  925. ******************************************************************************)
  926. {$F+} procedure defaultHandler; assembler; {$F-}
  927. asm
  928.    push ds; { save TP mouse driver }
  929.    mov ax, SEG @data;
  930.    mov ds, ax; { ds = TP:ds, not the driver's ds }
  931.    mov eventX, cx; { where in the x region did it occur }
  932.    mov eventY, dx;
  933.    mov eventButtons, bx;
  934.    mov eventHappened, 1; { eventHapppened := true }
  935.    pop ds; { restore driver's ds }
  936.    ret;
  937. end;
  938.  
  939. {   this is the default event handler , it simulates :
  940.  
  941.       begin
  942.            eventX := cx;
  943.            eventY := dx;
  944.            eventButtons := bx;
  945.            eventhappened := True;
  946.       end;
  947.  
  948. }
  949.  
  950. (******************************************************************************
  951. *                                doPascalStuff                                *
  952. * this is the pascal stuff that is called when vgaTextGraphicCursor mode has  *
  953. * to update the screen.                                                       *
  954. ******************************************************************************)
  955. procedure doPascalStuff; far;
  956. begin
  957.    if (mouseCursorLevel > 0) then begin
  958.       if (hasStoredArray) then begin
  959.          VGAscreen2Array(false, false, false); { move old array to screen - restore }
  960.          hasStoredArray := false;
  961.       end;
  962.       if (mouseCursorLevel > 0) then begin
  963.          VGAscreen2Array(true, true, false); { move new - from screen to array }
  964.          hasStoredArray := true; { now we have a stored array }
  965.          drawVGATextGraphicCursor; { do the low level stuff here }
  966.          lastEventX := eventX;
  967.          lastEventY := eventY; { this is the old location }
  968.       end; { go ahead and draw it ... }
  969.    end; { cursorLevel > 0 }
  970. end; {doPascalStuff}
  971.  
  972. (******************************************************************************
  973. *                            vgaTextGraphicHandler                            *
  974. * this is the same as default handler, only we do the mouse location movement *
  975. * ourself. Notice - if you use another handler, for mouse movement with       *
  976. * VGA text graphic cursor - do the same !!!                                   *
  977. ******************************************************************************)
  978. procedure vgaTextGraphicHandler; far; assembler;
  979. label
  980.    noCursorMove;
  981. asm
  982.    push ds; { save TP mouse driver }
  983.    push ax;
  984.    mov ax, SEG @data;
  985.    mov ds, ax; { ds = TP:ds, not the driver's ds }
  986.    pop ax; { ax has the reason .. }
  987.    mov eventX, cx; { where in the x region did it occur }
  988.    mov eventY, dx;
  989.    mov eventButtons, bx;
  990.    mov eventHappened, 1; { eventHapppened := true }
  991.    and ax, CURSOR_LOCATION_CHANGED; { o.k., do we need to handle mouse movement ? }
  992.    jz noCursorMove;
  993.    call doPascalStuff;
  994.    mov eventHappened, 0; 
  995.    { NOTICE - no movement events are detected in the out world ! - this is a
  996.      wintext consideration - It might be needed to track mouse movements, 
  997.      and then it should be changed ! - but this is MY default handler ! }
  998. noCursorMove: { no need for cursor movement handling }
  999.    pop ds; { restore driver's ds }
  1000. end; {vgaTextGraphicHandler}
  1001.  
  1002. (******************************************************************************
  1003. *                                GetLastEvent                                 *
  1004. ******************************************************************************)
  1005. function GetLastEvent(var x,y : word;
  1006.     var left_button,right_button,middle_button : buttonState) : boolean;
  1007.  
  1008. begin
  1009.     getLastEvent := eventhappened; {indicate if any event happened}
  1010.     eventhappened := False; {clear to next read/event}
  1011.     x := eventX;
  1012.     y := eventY;
  1013.     if ((eventButtons and LEFTBUTTON) <> 0) then
  1014.         left_button := buttonDown
  1015.     else left_button := buttonUp;
  1016.     if ((eventButtons and RIGHTBUTTON) <> 0) then
  1017.         right_button := buttonDown
  1018.     else right_button := buttonUp;
  1019.     if ((eventButtons and MIDDLEBUTTON) <> 0) then
  1020.         middle_button := buttonDown
  1021.     else middle_button := buttonUp;
  1022. end; {getLastEvent}
  1023.  
  1024. (******************************************************************************
  1025. *                              setDefaultHandler                              *
  1026. ******************************************************************************)
  1027. procedure setDefaultHandler;
  1028.  
  1029. {get only event mask, and set event handler to defaultHandler}
  1030.  
  1031. begin
  1032.    if (vgaTextGraphicCursor) then begin
  1033.       mask := mask or CURSOR_LOCATION_CHANGED; { we MUST detect cursor movement }
  1034.        setEventHandler(mask,@vgaTextGraphicHandler);
  1035.    end else
  1036.        setEventHandler(mask,@defaultHandler);
  1037. end; {setDefaultHandler}
  1038.  
  1039. (******************************************************************************
  1040. *                           enableLightPenEmulation                           *
  1041. ******************************************************************************)
  1042. procedure enableLightPenEmulation;
  1043.  
  1044. begin
  1045.     reg.ax := 13;
  1046.     callMouse;
  1047. end; {enableLightPenEmulation}
  1048.  
  1049. (******************************************************************************
  1050. *                          disableLightPenEmulation                           *
  1051. ******************************************************************************)
  1052. procedure disableLightPenEmulation;
  1053.  
  1054. begin
  1055.     reg.ax := 14;
  1056.     callMouse;
  1057. end;  {disableLightPenEmulation}
  1058.  
  1059. (******************************************************************************
  1060. *                              defineSensetivity                              *
  1061. ******************************************************************************)
  1062. procedure defineSensetivity(x,y : word);
  1063.  
  1064. begin
  1065.     reg.ax := 15;
  1066.     reg.cx := x; {# of mouse motions to horizontal 8 pixels}
  1067.     reg.dx := y; {# of mouse motions to vertical 8 pixels}
  1068.     callMouse;
  1069.     XMotions := x;
  1070.     YMotions := y; {update global unit variables}
  1071. end; {defineSensetivity}
  1072.  
  1073. (******************************************************************************
  1074. *                              setHideCursorBox                               *
  1075. ******************************************************************************)
  1076. procedure setHideCursorBox(left,top,right,bottom : word);
  1077.  
  1078. begin
  1079.     reg.ax := 16;
  1080.     reg.es := seg(HideBox);
  1081.     reg.dx := ofs(HideBox);
  1082.     HideBox.left := left;
  1083.     HideBox.right := right;
  1084.     HideBox.top := top;
  1085.     HideBox.bottom := bottom;
  1086.     callMouse;
  1087. end; {setHideCursorBox}
  1088.  
  1089. (******************************************************************************
  1090. *                         defineDoubleSpeedTreshHold                          *
  1091. ******************************************************************************)
  1092. procedure defineDoubleSpeedTreshHold(treshHold : word);
  1093.  
  1094. begin
  1095.     reg.ax := 17;
  1096.     reg.dx := treshHold;
  1097.     callMouse;
  1098. end; {defineDoubleSpeedTreshHold - from what speed to double mouse movement}
  1099.  
  1100. (******************************************************************************
  1101. *                              disableTreshHold                               *
  1102. ******************************************************************************)
  1103. procedure disableTreshHold;
  1104.  
  1105. begin
  1106.     defineDoubleSpeedTreshHold($7FFF);
  1107. end; {disableTreshHold}
  1108.  
  1109. (******************************************************************************
  1110. *                              defaultTreshHold                               *
  1111. ******************************************************************************)
  1112. procedure defaultTreshHold;
  1113.  
  1114. begin
  1115.     defineDoubleSpeedTreshHold(64);
  1116. end; {defaultTreshHold}
  1117.  
  1118. (******************************************************************************
  1119. *                                setMouseGraph                                *
  1120. ******************************************************************************)
  1121. procedure setMouseGraph;
  1122.  
  1123. begin
  1124.     mouseGraph := True;
  1125.    vgaTextGraphicCursor := false; { this must be turned off ! }
  1126. end; {setMouseGraph}
  1127.  
  1128. (******************************************************************************
  1129. *                               resetMouseGraph                               *
  1130. ******************************************************************************)
  1131. procedure resetMouseGraph;
  1132.  
  1133. begin
  1134.     mouseGraph := False;
  1135. end; {resetMouseGraph}
  1136.  
  1137.  
  1138. (******************************************************************************
  1139. *                               waitForRelease                                *
  1140. * Wait until button is release, or timeOut 1/100 seconds pass. (might miss a  *
  1141. * tenth (1/10) of a second.                                                                 *
  1142. ******************************************************************************)
  1143. procedure waitForRelease;
  1144. var
  1145.     sHour, sMinute, sSecond, sSec100 : word;    { Time at start }
  1146.     cHour, cMinute, cSecond, cSec100 : word;    { Current time    }
  1147.     stopSec                 : longInt;
  1148.     currentSec              : longInt;
  1149.     Delta                 : longInt;
  1150. begin
  1151.     getTime(sHour, sMinute, sSecond, sSec100);
  1152.     stopSec := (sHour*36000 + sMinute*600 + sSecond*10 + sSec100 + timeOut) mod
  1153.                 (24*360000);
  1154.     repeat
  1155.        getTime(cHour, cMinute, cSecond, cSec100);
  1156.        currentSec := (cHour*36000 + cMinute*600 + cSecond*10 + cSec100);
  1157.        Delta := currentSec - stopSec;
  1158.     until (not ButtonPressed) or (Delta >=0) and (Delta < 36000);
  1159. end; {waitForRelease}
  1160.  
  1161. (******************************************************************************
  1162. *                              swapEventHandler                               *
  1163. * handler is a far routine.                                                   *
  1164. ******************************************************************************)
  1165. procedure swapEventHandler;
  1166. begin
  1167.    reg.ax := $14;
  1168.    reg.cx := mask;
  1169.     reg.es := seg(handler^);
  1170.     reg.dx := ofs(handler^);
  1171.     callMouse;
  1172.    lastMask := reg.cx;
  1173.    lastHandler := ptr(reg.es,reg.dx);
  1174. end; {swapEventHandler}
  1175.  
  1176. (******************************************************************************
  1177. *                            getMouseSaveStateSize                            *
  1178. ******************************************************************************)
  1179. function getMouseSaveStateSize;
  1180. begin
  1181.    reg.ax := $15;
  1182.    callMouse;
  1183.    getMouseSaveStateSize := reg.bx;
  1184. end; {getMouseSaveStateSize}
  1185.  
  1186. (******************************************************************************
  1187. *                               interceptMouse                                *
  1188. ******************************************************************************)
  1189. procedure interceptMouse;
  1190. begin
  1191.    with reg do begin
  1192.       ax := 3;
  1193.       callMouse; { get place .. }
  1194.       interceptX := cx;
  1195.       interceptY := dx;
  1196.       ax := 31;
  1197.       callMouse;
  1198.    end; { disable mouse driver .. }
  1199. end; {interceptMouse}
  1200.  
  1201. (******************************************************************************
  1202. *                                restoreMouse                                 *
  1203. ******************************************************************************)
  1204. procedure restoreMouse;
  1205. begin
  1206.    with reg do begin
  1207.       ax := 32; { restore mouse driver .. }
  1208.       callMouse;
  1209.       ax := 4;
  1210.       cx := interceptX;
  1211.       dx := interceptY;
  1212.       callMouse;
  1213.    end; { with .. }
  1214. end; {restoreMouse}
  1215.  
  1216. (******************************************************************************
  1217. *                           setVgaTextGraphicCursor                           *
  1218. ******************************************************************************)
  1219. procedure setVgaTextGraphicCursor;
  1220. begin
  1221.    vgaTextGraphicCursor := false; { assume we can not .. }
  1222.    if (DESQviewActive) then
  1223.       exit; { tpDESQ tells us - DV is up, and we can not do anything about it .. }
  1224.    if (queryAdapterType <> vgaColor) then
  1225.       exit;
  1226.    vgaTextGraphicCursor := true; 
  1227. end; {setVgaTextGraphicCursor}
  1228.  
  1229. (******************************************************************************
  1230. *                          resetVgaTextGraphicCursor                          *
  1231. ******************************************************************************)
  1232. procedure resetVgaTextGraphicCursor;
  1233. begin
  1234.    vgaTextGraphicCursor := false; { assume we can not .. }
  1235. end; {resetVgaTextGraphicCursor}
  1236.  
  1237. var
  1238.     OldExitProc : pointer;
  1239.  
  1240. (******************************************************************************
  1241. *                                 MyExitProc                                  *
  1242. ******************************************************************************)
  1243. {$f+}procedure MyExitProc;
  1244. begin
  1245.     ExitProc := OldExitProc;
  1246.     if (vgaTextGraphicCursor and hasStoredArray) then
  1247.       vgaScreen2Array(false, false, false);
  1248.     dispose(charDefs);
  1249.     resetMouseGraph;
  1250.     resetVGATextGraphicCursor;
  1251.     initMouse;
  1252. end; { myExitProc }
  1253.  
  1254. { if this unit is used with a graphic unit that is loaded and executed after
  1255.      this unit in the Uses clause, the mouse initialization will not be
  1256.      correct, be sure to call initMouse in your program start to work
  1257.      properly }
  1258.  
  1259. begin    {unit initialization}
  1260.    eventX := 0;
  1261.    eventY := 0;
  1262.    eventHappened := false; { initialize ... }
  1263.    new(charDefs);
  1264.     initMouse; {detect in global variables}
  1265.     setArrowCursor; {start like that in graphic mode}
  1266.     OldExitProc := ExitProc;
  1267.     ExitProc    := @MyExitProc;
  1268. end. {mouseLib}
  1269.